package com.load.loaders.imp;

import java.util.*;

import org.apache.log4j.Logger;
import org.tmatesoft.svn.core.SVNLogEntryPath;
import org.tmatesoft.svn.core.io.SVNRepository;

import com.database.daos.IElementDao;
import com.database.objects.*;
import com.load.batch.BatchExecutor;
import com.load.factories.FileFactory;
import com.load.loaders.ILoader;
import com.load.utils.FileUtil;

public class LoaderCommit implements ILoader {

	private static Logger logger = Logger.getLogger("load.repository");

	private IElementDao elementDao;

	private LoaderFile loaderFile;

	@Override
	public void loadChilds(SVNRepository svnRepository, Type type, Element<?, ?> element, BatchExecutor executor) {
		Commit commit = (Commit) element;
		logger.info("COMMIT: " + commit.getNumber());

		Map<?, ?> changedPaths = commit.getEntry().getChangedPaths();
		filterFiles(changedPaths);

		executor.setStatus("Loading " + changedPaths.size() + " files of Commit " + commit.getNumber());
		logger.info("COMMIT: " + commit.getNumber() + " - " + changedPaths.size() + " files");

		int index = 1;
		for (Object keyPath : changedPaths.keySet()) {
			SVNLogEntryPath entryPath = (SVNLogEntryPath) changedPaths.get(keyPath);
			File file = buildFile(svnRepository, commit, entryPath);
			logger.info("FILE: " + index + " - " + entryPath.getPath());
			index++;
			if (type.impliesClass()) {
				loaderFile.loadChilds(svnRepository, type, file, executor);
			}
		}
	}

	private void filterFiles(Map<?, ?> changedPaths) {
		Iterator<?> iterator = changedPaths.keySet().iterator();
		while (iterator.hasNext()) {
			Object key = iterator.next();
			SVNLogEntryPath value = (SVNLogEntryPath) changedPaths.get(key);
			if (!FileUtil.pathIsFile(value.getPath())) {
				iterator.remove();
			}
		}
	}

	private File buildFile(SVNRepository svnRepository, Commit commit, SVNLogEntryPath entryPath) {
		File file = commit.getChildByLabel(entryPath.getPath());
		if (file != null) {
			file.setBaos(svnRepository);
			return file;
		}

		file = FileFactory.createFile(commit, entryPath);
		file.setBaos(svnRepository);
		elementDao.saveElement(file);
		return file;
	}

	public void setElementDao(IElementDao elementDao) {
		this.elementDao = elementDao;
	}

	public void setLoaderFile(LoaderFile loaderFile) {
		this.loaderFile = loaderFile;
	}

}